home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / kernel / dev / ds5000.md / devSCSIC90Mach.c < prev    next >
C/C++ Source or Header  |  1992-12-18  |  7KB  |  251 lines

  1. /* 
  2.  * devSCSIC90Mach.c --
  3.  *
  4.  *    Routines specific to the SCSI NCR 53C9X Host Adaptor which
  5.  *    depend on the machine architecture.
  6.  *
  7.  * Copyright 1991 Regents of the University of California
  8.  * Permission to use, copy, modify, and distribute this
  9.  * software and its documentation for any purpose and without
  10.  * fee is hereby granted, provided that the above copyright
  11.  * notice appear in all copies.  The University of California
  12.  * makes no representations about the suitability of this
  13.  * software for any purpose.  It is provided "as is" without
  14.  * express or implied warranty.
  15.  */
  16.  
  17. #ifndef lint
  18. static char rcsid[] = "$Header: /cdrom/src/kernel/Cvsroot/kernel/dev/ds5000.md/devSCSIC90Mach.c,v 1.3 91/08/19 13:49:56 jhh Exp $ SPRITE (Berkeley)";
  19. #endif /* not lint */
  20.  
  21. #include "sprite.h"
  22. #include "scsiC90.h"
  23. #include "mach.h"
  24. #include "dev.h"
  25. #include "devInt.h"
  26. #include "scsiHBA.h"
  27. #include "scsiDevice.h"
  28. #include "sync.h"
  29. #include "stdio.h"
  30. #include "stdlib.h"
  31. #include "string.h"
  32. #include "bstring.h"
  33. #include "devSCSIC90.h"
  34. #include "devSCSIC90Int.h"
  35. #include "dbg.h"
  36.  
  37. extern Boolean DevEntryAvailProc();
  38.  
  39.  
  40. /*
  41.  *----------------------------------------------------------------------
  42.  *
  43.  * DevReset --
  44.  *
  45.  *    Reset a SCSI bus controlled by the SCSI-3 Sun Host Adaptor.
  46.  *
  47.  * Results:
  48.  *    None.
  49.  *
  50.  * Side effects:
  51.  *    Reset the controller and SCSI bus.
  52.  *
  53.  *----------------------------------------------------------------------
  54.  */
  55. void
  56. DevReset(ctrlPtr)
  57.     Controller *ctrlPtr;
  58. {
  59.     volatile CtrlRegs *regsPtr = (volatile CtrlRegs *)ctrlPtr->regsPtr;
  60.     Device *devPtr;
  61.     int i,j;
  62.  
  63.     if (devSCSIC90Debug > 3) {
  64.     printf("Reset\n");
  65.     }
  66.     /* Reset scsi controller. */
  67.     regsPtr->scsi_ctrl.write.command = CR_RESET_CHIP;
  68.     regsPtr->scsi_ctrl.write.command = CR_DMA | CR_NOP;
  69.     /*
  70.      * Don't interrupt when the SCSI bus is reset. Set our bus ID to 7.
  71.      */
  72.     regsPtr->scsi_ctrl.write.config1 |= C1_REPORT | 0x7;
  73.     regsPtr->scsi_ctrl.write.command = CR_RESET_BUS;
  74.     for (i=0; i<8; i++) {
  75.     for (j=0; j<8; j++) {
  76.         devPtr = ctrlPtr->devicePtr[i][j];
  77.         if ((devPtr != (Device *)NIL) && (devPtr != (Device *)0)) {
  78.         devPtr->synchPeriod = 0;
  79.         devPtr->synchOffset = 0;
  80.         }
  81.     }
  82.     }
  83.     /*
  84.      * We initialize configuration, clock conv, synch offset, etc, in
  85.      * SendCommand.
  86.      * Parity is disabled by hardware reset or software.
  87.      */
  88.  
  89.     return;
  90. }
  91.  
  92.  
  93. /*
  94.  *----------------------------------------------------------------------
  95.  *
  96.  * DevStartDMA --
  97.  *
  98.  *    Issue the sequence of commands to the controller to start DMA.
  99.  *    This can be called by Dev_SCSIC90Intr in response to a DATA_{IN,OUT}
  100.  *    phase message.
  101.  *
  102.  * Results:
  103.  *    None.
  104.  *
  105.  * Side effects:
  106.  *    DMA is enabled.  No registers other than the control register are
  107.  *    to be accessed until DMA is disabled again.
  108.  *
  109.  *----------------------------------------------------------------------
  110.  */
  111. void
  112. DevStartDMA(ctrlPtr)
  113.     Controller *ctrlPtr;
  114. {
  115.     volatile CtrlRegs    *regsPtr;
  116.     int            size;
  117.     Device              *devPtr = ctrlPtr->devPtr;
  118.     Address             buffer;
  119.  
  120.     size = devPtr->activeBufLen;
  121.     buffer = devPtr->activeBufPtr;
  122.  
  123.     if (devSCSIC90Debug > 4) {
  124.     printf("StartDMA called for %s, dma %s, size = %d.\n", ctrlPtr->name,
  125.         (devPtr->dmaState == DMA_RECEIVE) ? "receive" :
  126.         ((devPtr->dmaState == DMA_SEND) ? "send" :
  127.                           "not-active!"), size);
  128.     }
  129.     if (devPtr->dmaState == DMA_INACTIVE) {
  130.     printf("StartDMA: Returning, since DMA state isn't active.\n");
  131.     return;
  132.     }
  133.     regsPtr = ctrlPtr->regsPtr;
  134.     if (buffer == (Address) NIL) {
  135.     panic("DMA buffer was NIL before dma.\n");
  136.     }
  137.     if (devPtr->dmaState == DMA_RECEIVE) {
  138.     *ctrlPtr->dmaRegPtr = 0;
  139.     } else {
  140.     bcopy((char *) buffer, ctrlPtr->buffer, size);
  141.     *ctrlPtr->dmaRegPtr = (unsigned int) DMA_WRITE;
  142.     }
  143.     /*
  144.      * Put transfer size in counter.  If this is 16k (max size), this puts
  145.      * a 0 in the counter, which is the correct thing to do.
  146.      */
  147.     /* High byte of size. */
  148.     regsPtr->scsi_ctrl.write.xCntHi = (unsigned char) ((size & 0xff00) >> 8);
  149.     /* Low byte of size. */
  150.     regsPtr->scsi_ctrl.write.xCntLo = (unsigned char) (size & 0x00ff);
  151.     /* Load count into counter by writing a DMA NOP command on C90 only */
  152.     regsPtr->scsi_ctrl.write.command = CR_DMA | CR_NOP;
  153.     /* Start scsi command. */
  154.     regsPtr->scsi_ctrl.write.command = CR_DMA | CR_XFER_INFO;
  155.  
  156.     return;
  157. }
  158.  
  159.  
  160. /*
  161.  *----------------------------------------------------------------------
  162.  *
  163.  * DevSCSIC90Init --
  164.  *
  165.  *    Check for the existant of the Sun SCSIC90 HBA controller. If it
  166.  *    exists allocate data stuctures for it.
  167.  *
  168.  * Results:
  169.  *    TRUE if the controller exists, FALSE otherwise.
  170.  *
  171.  * Side effects:
  172.  *    Memory may be allocated.
  173.  *
  174.  *----------------------------------------------------------------------
  175.  */
  176. ClientData
  177. DevSCSIC90Init(ctrlLocPtr)
  178.     DevConfigController    *ctrlLocPtr;    /* Controller location. */
  179. {
  180.     int            ctrlNum;
  181.     Controller         *ctrlPtr;
  182.     int            i,j;
  183.     Mach_SlotInfo    slotInfo;
  184.     char        *slotAddr;
  185.     static char        *vendor = "DEC";
  186.     static char        *module = "PMAZ-AA";
  187.     ReturnStatus    status;
  188.     static int numSCSIC90Controllers = 0; /* highest controller we've
  189.                        * probed for */
  190.  
  191.     slotAddr = (char *) MACH_IO_SLOT_ADDR(ctrlLocPtr->slot);
  192.  
  193.     status = Mach_GetSlotInfo(slotAddr + ROM_OFFSET, &slotInfo);
  194.     if (status != SUCCESS) {
  195.     return DEV_NO_CONTROLLER;
  196.     }
  197.     if (strcmp(slotInfo.vendor, vendor) || strcmp(slotInfo.module, module)) {
  198.     return DEV_NO_CONTROLLER;
  199.     }
  200.     /*
  201.      * It's there. Allocate and fill in the Controller structure.
  202.      */
  203.     ctrlNum = ctrlLocPtr->controllerID;
  204.     if (ctrlNum >= MAX_SCSIC90_CTRLS) {
  205.     printf("DevSCSIC90Init: too many controllers\n");
  206.     return DEV_NO_CONTROLLER;
  207.     }
  208.     if (ctrlNum+1 > numSCSIC90Controllers) {
  209.     numSCSIC90Controllers = ctrlNum+1;
  210.     }
  211.     Controllers[ctrlNum] = ctrlPtr = (Controller *) malloc(sizeof(Controller));
  212.     bzero((char *) ctrlPtr, sizeof(Controller));
  213.     ctrlPtr->regsPtr = (volatile CtrlRegs *) (slotAddr + REG_OFFSET);
  214.     ctrlPtr->dmaRegPtr = (volatile DMARegister *) (slotAddr + DMA_OFFSET);
  215.     ctrlPtr->buffer = slotAddr + BUFFER_OFFSET;
  216.     ctrlPtr->name = ctrlLocPtr->name;
  217.     ctrlPtr->slot = ctrlLocPtr->slot;
  218.     Sync_SemInitDynamic(&(ctrlPtr->mutex), ctrlPtr->name);
  219.     printf("SCSI controller \"%s\" in slot %d (%s %s %s %s)\n",
  220.     ctrlPtr->name, ctrlPtr->slot, slotInfo.module, slotInfo.vendor, 
  221.     slotInfo.revision, slotInfo.type);
  222.     /* 
  223.      * Initialized the name, device queue header, and the master lock.
  224.      * The controller comes up with no devices active and no devices
  225.      * attached.  Reserved the devices associated with the 
  226.      * targetID of the controller (7).
  227.      */
  228.     ctrlPtr->devPtr = (Device *)NIL;
  229.     ctrlPtr->interruptDevPtr = (Device *)NIL;
  230.     ctrlPtr->devQueuesMask = 0;
  231.     ctrlPtr->devQueues = Dev_CtrlQueuesCreate(&(ctrlPtr->mutex),
  232.         DevEntryAvailProc);
  233.     for (i = 0; i < 8; i++) {
  234.     for (j = 0; j < 8; j++) {
  235.         ctrlPtr->devicePtr[i][j] = (i == 7) ? (Device *) 0 : (Device *) NIL;
  236.     }
  237.     }
  238.     Controllers[ctrlNum] = ctrlPtr;
  239.     Mach_SetIOHandler(ctrlPtr->slot, (void (*)()) DevSCSIC90Intr, 
  240.     (ClientData) ctrlPtr);
  241.     DevReset(ctrlPtr);
  242.  
  243.     if (devSCSIC90Debug > 3) {
  244.     printf("devSCSIC90Init: controller 0x%02x initialized.\n", ctrlNum);
  245.     }
  246.  
  247.     return (ClientData) ctrlPtr;
  248. }
  249.  
  250.  
  251.